<?php
// +----------------------------------------------------------------------
// | LikeShop100%开源免费商用电商系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码，建议反馈是我们前进的动力
// | 开源版本可自由商用，可去除界面版权logo
// | 商业版本务必购买商业授权，以免引起法律纠纷
// | 禁止对系统程序代码以任何目的，任何形式的再发布
// | Gitee下载：https://gitee.com/likeshop_gitee/likeshop
// | 访问官网：https://www.likemarket.net
// | 访问社区：https://home.likemarket.net
// | 访问手册：http://doc.likemarket.net
// | 微信公众号：好象科技
// | 好象科技开发团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------

// | Author: LikeShopTeam-段誉
// +----------------------------------------------------------------------

namespace app\api\logic;

use app\api\model\{Coupon, Order, User};
use app\common\logic\AccountLogLogic;
use app\common\logic\{
    LogicBase,
    OrderGoodsLogic,
    OrderLogLogic,
    OrderRefundLogic,
    PayNotifyLogic};
use app\common\model\AccountLog;
use app\common\model\{Client_, MessageScene_, OrderLog, Pay, Order as CommonOrder};
use app\common\server\{ConfigServer, UrlServer};
use think\Db;
use think\Exception;
use expressage\{
    Kdniao,
    Kd100
};
use think\facade\Env;
use think\facade\Hook;
use think\helper\hash\Bcrypt;


class OrderLogic extends LogicBase
{

    // 下一步
    protected static $status = [
        0 => [2, 4, 5],
        1 => [0, 4, 5],
        2 => [3, 4, 5],
        3 => [6],
    ];

    /**
     * 结算详情
     * @param $post
     * @param $user_id
     * @return array|bool
     */
    public static function info($post, $user)
    {
//        try {
        if (!$user) {
            return self::dataError("用户不存在");
        }
        $goods = $post['goods_id'];

//        if (count($goods) < 40 || count($goods) > 120) {
//            return self::dataError("商品数量不得小于40且不得大于120");
//        }

        // $goods = str_replace('[', '', $goods);
        // $goods = str_replace(']', '', $goods);

        $infos = self::getGoodsColumn(implode(',', $goods));

        if (!$infos) {
            return self::dataError("商品查询失败");
        }

        foreach ($goods as $k => $good) {
            if (!isset($infos[$good])) {
                continue;
            }
            $goods_info = $infos[$good];

            $image_str = empty($goods_info['spec_image']) ? $goods_info['image'] : $goods_info['spec_image'];
            $goods_info['image_str'] = UrlServer::getFileUrl($image_str);

            //订单商品信息
            $result[$goods_info['supplier_id']][] = [
                'goods_id' => $good,
                'brand_id' => $goods_info['brand_id'],
                'goods_name' => $goods_info['name'],
                'goods_num' => isset($post['goods_num']) ? intval($post['goods_num']) : 1,
                'image' => $goods_info['image'],
                'goods_links' => $goods_info['goods_links'],
                'coupon' => intval($goods_info['coupon']),
                'goods_price' => round($goods_info['good_price'], 2),
                'supplier_id' => $goods_info['supplier_id'],
                'platform' => isset($goods_info['platform']) ? $goods_info['platform'] : "",
                'welfare' => $goods_info['welfare'] ?? json_encode([]),
                "create_time" => time()
            ];
        }

        return self::dataSuccess('', $result);
//        } catch (\Exception $e) {
//            return self::dataError($e->getMessage());
//        }
    }


    /**
     * Notes: 计算优惠金额
     * @param $goods
     * @param $cl_id
     * @author 段誉(2021/1/30 14:44)
     * @return array
     * @throws Exception
     * 1,找出商品在优惠条件中的 总商品金额和商品数量
     * 2,计算出每个商品可获得的优惠金额,最后一个商品,用总优惠券金额 - 已优惠金额
     */
    public static function calculateDiscountAmount($goods, $cl_id)
    {
        $coupon = Coupon::getCouponByClId($cl_id);

        if (empty($coupon)) {
            return ['goods' => $goods, 'total_discount' => 0];
        }

        //与优惠券关联的商品id
        $coupon_goods = Db::name('coupon_goods')
            ->where(['coupon_id' => $coupon['id']])
            ->column('goods_id');

        $coupon_goods_data = self::discountGoods($goods, $coupon, $coupon_goods);
        $goods_count = $coupon_goods_data['count'];//可以优惠的商品数量
        $total_goods_price = $coupon_goods_data['discount_goods'];//可以优惠的商品总金额

        $total_discount = 0;
        $discount = 0;//每件商品优惠金额
        $check_num = 0;
        foreach ($goods as &$good) {
            //指定可用时
            if ($coupon['use_goods_type'] == 2 && !in_array($good['goods_id'], $coupon_goods)) {
                continue;
            }
            //指定不可用
            if ($coupon['use_goods_type'] == 3 && in_array($good['goods_id'], $coupon_goods)) {
                continue;
            }

            $discount = ($good['goods_price'] * $good['goods_num']) / $total_goods_price * $coupon['money'];
            $discount = round($discount, 2);
            if ($discount > $good['goods_price']) {
                $discount = $good['goods_price'];
            }
            $good['discount_price'] = $discount;//每个商品优惠的金额

            //用于判断当前是否为最后一个商品
            if (($check_num + 1) == $goods_count) {
                $discount = $coupon['money'] - $total_discount;
                if ($discount > $good['goods_price']) {
                    $discount = $good['goods_price'];
                }
            }

            $check_num += 1;
            $total_discount += $discount;
        }

        return [
            'goods' => $goods,
            'total_discount' => round($total_discount, 2),
        ];
    }


    /**
     * Notes: 订单中优惠商品的总价
     * @param $goods
     * @param $coupon
     * @param $coupon_goods
     * @author 段誉(2021/1/30 14:45)
     * @return array
     * @throws Exception
     */
    public static function discountGoods($goods, $coupon, $coupon_goods)
    {
        $discount_goods = 0;
        $count = 0;

        //1-全部商品；2-指定商品；3-指定商品不可用
        foreach ($goods as $good) {
            if ($coupon['use_goods_type'] == 1) {
                $discount_goods += $good['goods_price'] * $good['goods_num'];
                $count += 1;
            }

            if (($coupon['use_goods_type'] == 2) && in_array($good['goods_id'], $coupon_goods)) {
                $discount_goods += $good['goods_price'] * $good['goods_num'];
                $count += 1;
            }

            if ($coupon['use_goods_type'] == 3 && !in_array($good['goods_id'], $coupon_goods)) {
                $discount_goods += $good['goods_price'] * $good['goods_num'];
                $count += 1;
            }
        }

        if ($coupon['condition_type'] == 2 && $discount_goods < $coupon['condition_money']) {
            throw new Exception('所结算的商品中未满足使用的金额');
        }


        return $data = [
            'count' => $count,
            'discount_goods' => $discount_goods,
        ];
    }


    /**
     * Notes:获取指定商品信息
     * @param $item_ids
     * @author 段誉(2021/1/30 14:45)
     * @return array
     */
    public static function getGoodsColumn($item_ids)
    {
//        $field = 'i.id as item_id,g.id as goods_id,g.name as goods_name,g.status,g.del,g.image,i.stock,
//        g.free_shipping_type,g.free_shipping,g.free_shipping_template_id,g.image, i.image as spec_image,
//        i.spec_value_str,i.spec_value_ids,i.price as goods_price,i.image as spec_image,i.volume,
//        i.weight,g.first_category_id,g.second_category_id,g.third_category_id';

//        $goods = Db::name('goods g')
//            ->join('goods_item i', 'g.id = i.goods_id')
//            ->where('i.id', 'in', $item_ids)
//            ->column($field, 'i.id');
        $field = "i.id as goods_id,i.name,i.brand_id,i.supplier_id,i.image,i.remark,i.goods_links,i.platform,i.welfare,i.commission,i.coupon,i.good_price,g.name as category_name";
        $goods = Db::name('goods i')
            ->leftJoin("goods_category g", "i.second_category_id = g.id")
            ->where([['i.id', 'in', $item_ids], ["status", "=", "2"], ["status", "=", "2"], ["validity", ">", time()]])
            ->column($field, 'i.id');

        return $goods;
    }


    /**
     * 添加订单
     * @param $user_info
     * @param $goods_data
     * @param $post
     * @return array|bool
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function add($user_info, $goods_data, $post, $cart)
    {
        Db::startTrans();
        try {
            $schedule_type = isset($post['schedule_type']) ? $post['schedule_type'] : 1; //  '档期类型 1基地直播  2 寄样直播'

            $where = [
                ["schedule", "=", date("Y-m-d", $post['schedule'] / 1000)],
                ["host_id", "=", $user_info['role']->id],
                ["del", "=", "0"],
            ];

            if ($schedule_type == 1) {
                $where[] = ["basis_id", "=", $post['basis_id']];
                $where[] = ["basis_studio_id", "=", $post['basis_studio_id']];
                $where[] = ["basis_studio_interval_id", "=", $post['basis_studio_interval_id']];
            }


            // 档期
            $schedule = Db::name("schedule")->where($where)->find(); // 档期
            if ($schedule) {
                return self::dataError('档期已存在');
            }

            $schedule_id = ScheduleLogic::add($user_info['role']->id, $post);

            if (!$schedule_id) {
                return self::dataError('档期生成失败');
            }


            if ($user_info['user_role'] == 1) {
                $order_type = \app\common\model\Order::HOST_ORDER;//主播订单
            } else {
                $order_type = \app\common\model\Order::SUPPLIER_ORDER;//商户订单
            }

            // 备注
            $user_remark = $post['user_remark'];
            $remark = [];
            foreach ($user_remark as $k => $v) {
                $remark[array_keys($v)[0]] = array_values($v)[0];
            }

            static $goods_count = 0;
            static $sample_price = 0;

            // 订单及订单商品
            foreach ($goods_data as $k => $v) {
                $supplier_id = $k;
                $total_price = 0;
                $total_num = 0;

                foreach ($v as $key => $val) {
                    $sn = createSn('order', 'order_sn', '', 4);
                    $order_sn[] = $sn;
                    $total_price += $val['goods_price'] * $cart[$val['goods_id']];
                    $total_num++; // @todo
                    $goods_count++;
                }

                $amount = $schedule_type == 1 ? $total_num : $total_price;
                if ($schedule_type == 1) {
                    $sample_price += intval($total_num);
                } else {
                    $sample_price += $total_price;
                }

                $order_data[] = [
                    'order_type' => $order_type,
                    'live_type' => isset($post['live_type']) ? intval($post['live_type']) : 1,
                    "schedule_type" => $schedule_type,
                    'platform' => isset($post['platform']) ? intval($post['platform']) : "",
                    'order_sn' => $sn,
                    'host_id' => $user_info['role']->id,
                    'supplier_id' => $supplier_id,
                    'total_price' => $total_price,
                    'mobile' => $user_info['role']->tel_number,
                    'order_amount' => $amount,
                    'user_remark' => isset($remark[$k]) ? $remark[$k] : "",
                    'order_remarks' => isset($post['order_remarks']) ? $post['order_remarks'] : "",
                    'create_time' => time(),
                    'schedule' => date("Y-m-d H:i:s", $post['schedule'] / 1000),
                    'schedule_id' => $schedule_id,
                ];
            }

            // 订单生成
            $goods_data = array_values($goods_data);
            $order = self::addOrder($order_data);

            // 订单商品
            $goods_list = array();
            foreach ($goods_data as $key => $val) {
                foreach ($val as $ks => $vs) {
                    foreach ($order as $k => $v) {
                        if ($vs['supplier_id'] == $v['supplier_id']) {
                            $goods_data[$k][$ks]['order_id'] = $v['order_id'];
                            unset($goods_data[$k][$ks]['supplier_id']);
                            unset($goods_data[$k][$ks]['schedule']);
                            $goods_list[] = $goods_data[$k][$ks];
                        }
                    }
                }
            }

            Db::name("order_goods")->insertAll($goods_list);

            // 订单后续(订单日志,)
            if (is_array($order)) {
                foreach ($order as $v) {
                    self::addOrderAfter($v['order_id'], $user_info['id'], 'cart', $goods_list);
                }
            } else {
                self::addOrderAfter($order['order_id'], $user_info['id'], 'cart', $goods_list);
            }

            // 修改档期中的商品数量和商品价格
            ScheduleLogic::orderAfter($schedule_id, [
                'goods_count' => $goods_count, // 商品数量
                'sample_price' => $sample_price, // 样品价格
                'basis_use' => isset($post['basis_id']) && $post['basis_id'] ? config("project.basis_use") : 0,
                'basis_staff' => isset($post['staffing']) && $post['staffing'] ? config("project.basis_staff") : 0,
            ]);

//            if ($data['order_amount'] == 0) {
//                PayNotifyLogic::handle('order', $order['order_sn'], []);
//            }

//            //短信通知
//            Hook::listen('sms_send', [
//                'key' => 'DDTJTZ',
//                'mobile' => $user['mobile'],
//                'params' => [
//                    'nickname' => $user->nickname,
//                    'order_sn' => $order['order_sn'],
//                ],
//            ]);

            foreach ($order as $k => $v) {
                $send_data[] = [
                    'msg_type' => 2,
                    'msg_title' => "订单生成通知",
                    'msg_content' => "您有新的订单生成,订单号为" . $v['order_sn'],
                    'to_user' => $v['supplier_id'],
                ];
            }
            foreach ($send_data as $v) {
                Hook::listen('UserMsg', $v);
            }

            Db::commit();
            return self::dataSuccess('订单提交成功', [
                'schedule_id' => $schedule_id,
                'order_id' => $order,
                'type' => 'order' . $order_type
            ]);

        } catch (Exception $e) {
            Db::rollback();
            return self::dataError($e->getMessage());
        }
    }


    /**
     * Notes:添加订单
     * @param $user_id
     * @param $data
     * @param $order_source
     * @param $user_address
     * @author 段誉(2021/1/30 14:46)
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function addOrder($order_data)
    {
        $order_sn = array();

        $order_num = Db::name('order')->insertAll($order_data);
        $order_id = Db::name('order')->getLastInsID();
        $ids = array();
        foreach ($order_data as $v) {
            $ids[] = [
                "order_id" => intval($order_id--),
                "supplier_id" => $v['supplier_id'],
                "order_sn" => $v['order_sn']
            ];
        }

        if ($order_num == count($order_data)) {
            return $ids;
        }
        return $order_num;
    }

    /**
     * Notes: 添加订单商品
     * @param $order_id
     * @param $goods_lists
     * @author 段誉(2021/1/30 14:46)
     * @throws Exception
     * @Deprecated  弃用
     */
    public static function addOrderGoods($order_id, $goods_lists)
    {
        foreach ($goods_lists as $k1 => $good) {
            //商品验证
            if ($good['del'] == 1 || $good['status'] != 1) {
                throw new Exception('包含不存在或已下架的商品,无法下单');
            }
//            if ($good['goods_num'] > $good['stock']) {
//                throw new Exception('商品库存不足,无法下单');
//            }

            $total_pay_price = ($good['goods_price'] * $good['goods_num']) - ($good['discount_price'] ?? 0);
            $total_pay_price = $total_pay_price <= 0 ? 0 : $total_pay_price;

            $goods_data[] = [
                'order_id' => $order_id,
                'goods_id' => $good['goods_id'],
                'item_id' => $good['item_id'],
                'goods_name' => $good['goods_name'],
                'goods_num' => $good['goods_num'],
                'goods_price' => $good['goods_price'],
                'total_price' => $good['goods_price'] * $good['goods_num'],
                'total_pay_price' => $total_pay_price,//实际支付商品金额(扣除优惠金额)
                'spec_value_ids' => $good['spec_value_ids'],
                'discount_price' => $good['discount_price'],
                'goods_info' => json_encode($good, JSON_UNESCAPED_UNICODE),
                'create_time' => time(),
            ];
        }
        Db::name('order_goods')->insertAll($goods_data);
    }


    /**
     * Notes:下单后操作
     * @param $order_id
     * @param $user_id
     * @param $type
     * @param $data
     * @author 段誉(2021/1/30 14:46)
     * @throws Exception
     * @throws \think\exception\PDOException
     */
    public static function addOrderAfter($order_id, $user_id, $type, $goods_data)
    {
//        $goods_data = $data['goods_lists'];

//        //下单时扣减商品库存
//        $deduct_type = ConfigServer::get('trading', 'deduct_type', '', 1);
//        if ($deduct_type == 1) {
//            OrderGoodsLogic::decStock($goods_data);
//        }
        //删除购物车商品
        if ($type == 'cart') {
            $cart_items = array_column($goods_data, 'goods_id');
            CartLogic::del($cart_items, $user_id);
        }

//        //有使用优惠券时更新coupon_list
//        if ($data['coupon_id'] > 0) {
//            \app\common\logic\CouponLogic::handleCouponByOrder($data['coupon_id'], $order_id);
//        }
        //增加订单日志
        OrderLogLogic::record(
            OrderLog::TYPE_USER,
            OrderLog::USER_ADD_ORDER,
            $order_id,
            $user_id,
            OrderLog::USER_ADD_ORDER
        );
    }


    /**
     * 订单列表
     * @param $user_id
     * @param $type
     * @param $page
     * @param $size
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getOrderList($user_id, $type, $page, $size)
    {
        $order = new Order();
        $where[] = ['del', '=', 0];
        $where[] = ['a.user_id', '=', $user_id];
//        订单状态;0待对方审核; 1待平台审核; 2主播开播审核; 3待直播; 4已作废; 5已拒绝申请;6已完成
        switch ($type) {
            case '0':
                $where[] = ['order_status', '=', CommonOrder::WAIT_AUDIT];
                break;
            case '1':
                $where[] = ['order_status', '=', CommonOrder::PLATFORM_AUDIT];
                break;
            case '2':
                $where[] = ['order_status', '=', CommonOrder::PLATFORM_AUDIT];
                break;
            case '3':
                $where[] = ['order_status', '=', CommonOrder::PLAY_AUDIT];
                break;
            case '4':
                $where[] = ['order_status', '=', CommonOrder::STATUS_CLOSE];
                break;
            case '5':
                $where[] = ['order_status', '=', CommonOrder::REFUSE_AUDIT];
                break;
            case '6':
                $where[] = ['order_status', '=', CommonOrder::DONE];
                break;
        }

        $order_count = $order->alias("a")->where(['del' => 0, 'a.user_id' => $user_id])
            ->where($where)
            ->count();

        $order_list = $order->alias("a")
            ->where(['del' => 0, 'a.user_id' => $user_id])
            ->where($where)
            ->leftJoin("supplier b", "a.supplier_id = b.id")
            ->field('a.id,order_sn,goods_name,goods_img,supplier_id,order_status,commission,order_type,a.create_time,a.update_time,store_name,store_url,tel_number as store_tel_number')
            ->page($page, $size)
            ->order('a.id desc')
            ->select();

        $order_list->append(['cancel_btn', 'order_cancel_time']);

//        foreach ($order_list as $list) {
//            foreach ($list['order_goods'] as &$order_goods) {
//                $order_good_info = json_decode($order_goods['goods_info'], true);
//                $order_goods['goods_name'] = $order_good_info['goods_name'];
//                $order_goods['spec_value'] = $order_good_info['spec_value_str'];
//                $image = empty($order_good_info['spec_image']) ? $order_good_info['image'] : $order_good_info['spec_image'];
//                $order_goods['image'] = UrlServer::getFileUrl($image);
//            }
//        }

        $data = [
            'list' => $order_list,
            'page' => $page,
            'size' => $size,
            'count' => $order_count,
            'more' => is_more($order_count, $page, $size)
        ];
        return $data;
    }

    /**
     * 订单详情
     * @param $order_id
     * @param $user_id
     * @return Order|array|null|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getOrderDetail($order_id, $user_id)
    {

        $order = new Order();

        $res = $order->field("order_type")->where("id", $order_id)->where("user_id", $user_id)->find();
        $result = array();
        if ($res['order_type'] == 1) {  // 商户订单
            $field = 'a.*,order_status as order_status_text,u.id as user_id,u.nickname,u.avatar,u.user_role,h.true_name,h.tel_number as h_tel_number,h.wx_code as host_wx,h.create_time as h_c_time,s.store_name,s.tel_number as s_tel_number,s.wx_code as s_wx,s.create_time as s_c_time';

            $result = $order->alias("a")
                ->leftJoin("user u", "a.user_id = u.id")
                ->leftJoin("supplier s", "s.user_id = u.id")
                ->leftJoin("the_host h", "h.user_id = u.id")
                ->leftJoin("the_host ot_ho", "ot_ho.id = a.supplier_id")
                ->field("ot_ho.true_name,ot_ho.wx_code as ot_wx,ot_ho.tel_number as ot_tel_number,ot_su.wx_code as ot_wx,ot_su.tel_number as ot_tel_number")
                ->field($field)
                ->where('a.id', $order_id)
                ->find();
        } elseif ($res['order_type'] == 0) { // 主播订单
            $field = 'a.*,order_status as order_status_text,u.id as user_id,u.nickname,u.avatar,u.user_role,h.true_name,h.tel_number as h_tel_number,h.wx_code as host_wx,h.create_time as h_c_time,s.store_name,s.tel_number as s_tel_number,s.wx_code as s_wx,s.create_time as s_c_time';
            $result = $order->alias("a")
                ->leftJoin("user u", "a.user_id = u.id")
                ->leftJoin("the_host h", "h.user_id = u.id")
                ->leftJoin("supplier s", "s.user_id = u.id")
                ->leftJoin("supplier ot_su", "ot_su.id = a.supplier_id")
                ->field("ot_su.id as ot_id,ot_su.store_name as su_store_name,ot_su.store_url,ot_su.user_id as ot_user_id,ot_su.tel_number as su_tel_number,ot_su.wx_code as su_wx,ot_su.create_time as su_c_time")
                ->field($field)
                ->where('a.id', $order_id)
                ->find();
        }


        return $result;
//        $order = Order::get(['del' => 0, 'id' => $order_id, 'user_id' => $user_id]);
//        if (!$order) {
//            return [];
//        }
//
//        $order_append = [
//            'delivery_address', 'pay_btn', 'cancel_btn', 'delivery_btn', 'take_btn', 'del_btn', 'order_cancel_time', 'pay_way_text'
//        ];
//        $order_hidden = [
//            'user_id', 'order_source', 'city', 'district', 'address', 'shipping_status', 'shipping_code',
//            'pay_status', 'transaction_id', 'del', 'province'
//        ];
//        $order->append($order_append)->hidden($order_hidden);

//        $refund_days = ConfigServer::get('after_sale', 'refund_days', 0) * 86400;
//        $now = time();
//        //显示是否评论按钮
//        foreach ($order->order_goods as &$item) {
//            $item['comment_btn'] = 0;
//            if ($order['pay_status'] == Pay::ISPAID && $order['order_status'] == CommonOrder::STATUS_FINISH && $item['is_comment'] == 0) {
//                $item['comment_btn'] = 1;
//            }
//            $item['refund_btn'] = 0;
//
//            $confirm_take_time = strtotime($order['confirm_take_time']) ?: 0;
//            $refund_time = $confirm_take_time + $refund_days;
//
//            if ($order['order_status'] == CommonOrder::STATUS_FINISH && $refund_time > $now && $item['refund_status'] == \app\common\model\OrderGoods::REFUND_STATUS_NO) {
//                $item['refund_btn'] = 1;
//            }
//
//            $goods_info = json_decode($item['goods_info'], true);
//            $item['goods_name'] = $goods_info['goods_name'];
//            $item['spec_value'] = $goods_info['spec_value_str'];
//            $item['image'] = empty($goods_info['spec_image']) ? UrlServer::getFileUrl($goods_info['image']) : UrlServer::getFileUrl($goods_info['spec_image']);
//        }
//        return $order;
    }


    /**
     * Notes: 取消订单
     * @param $order_id
     * @param $user_id
     * @author 段誉(2021/1/30 14:47)
     * @return array|bool
     */
    public static function cancel($order_id, $user_id, $user_info)
    {
//        $order = Order::get([
//            'del' => 0,
//            'user_id' => $user_id,
//            'id' => $order_id
//        ], ['orderGoods']);
//
//        if (!$order || $order['order_status'] > CommonOrder::STATUS_WAIT_DELIVERY) {
//            return self::dataError('很抱歉!订单无法取消');
//        }
//        Db::startTrans();
//        try {
//            //取消订单
//            OrderRefundLogic::cancelOrder($order_id, OrderLog::TYPE_USER);
//            //已支付的订单,取消,退款
//            if ($order['pay_status'] == Pay::ISPAID) {
//                //更新订单状态
//                OrderRefundLogic::cancelOrderRefundUpdate($order);
//                //订单退款
//                OrderRefundLogic::refund($order, $order['order_amount'], $order['order_amount']);
//            }
//
//            Db::commit();
//
//            Hook::listen('wx_message_send', [
//                'user_id' => $user_id,
//                'scene' => MessageScene_::REFUND_SUCCESS,
//                'order_id' => $order_id
//            ]);
//            return self::dataSuccess('取消成功');
//        } catch (Exception $e) {
//            Db::rollback();
//            //增加退款失败记录
//            OrderRefundLogic::addErrorRefund($order, $e->getMessage());
//            return self::dataError($e->getMessage());
//        }

        $order = Order::get(['del' => 0, 'id' => $order_id], ['order_goods']);

        // @todo
        $res = $order->save(['order_status' => \app\common\model\Order::STATUS_CLOSE, 'update_time' => time(), 'cancel_time' => time(), 'cancel_user_id' => $user_id]);
        if (!$res) {
            return self::dataError('订单取消失败');
        }
        if ($user_info['user_role'] && $user_info['user_role'] == 1) { // 主播取消
            OrderLogLogic::record(
                OrderLog::TYPE_USER,
                OrderLog::HOST_CANCEL_ORDER,
                $order_id,
                $user_info['id'],
                OrderLog::HOST_CANCEL_ORDER
            );
        } elseif ($user_info['user_role'] && $user_info['user_role'] == 2) { // 商户取消
            OrderLogLogic::record(
                OrderLog::TYPE_SHOP,
                OrderLog::SHOP_CANCEL_ORDER,
                $order_id,
                $user_info['id'],
                OrderLog::SHOP_CANCEL_ORDER
            );
        }
        return self::dataSuccess('取消成功');
    }


    /**
     * Notes: 删除订单
     * @param $order_id
     * @param $user_id
     * @author 段誉(2021/1/30 14:57)
     * @return array
     */
    public static function del($order_id, $user_id)
    {
        $order = Order::get([
            'order_status' => CommonOrder::STATUS_CLOSE,
            'user_id' => $user_id,
            'id' => $order_id,
            'del' => 0,
        ]);

        if (!$order) {
            return self::dataError('订单无法删除');
        }

        $order->save(['del' => 1, 'update_time' => time()]);

        OrderLogLogic::record(
            OrderLog::TYPE_USER,
            OrderLog::USER_DEL_ORDER,
            $order_id,
            $user_id,
            OrderLog::USER_DEL_ORDER
        );

        return self::dataSuccess('删除成功');
    }


    /**
     * Notes: 确认收货
     * @param $order_id
     * @param $user_id
     * @author 段誉(2021/1/30 14:57)
     * @return array
     */
    public static function confirm($order_id, $user_id)
    {
        $order = Order::get(['del' => 0, 'id' => $order_id]);
        if ($order['order_status'] == \app\common\model\Order::STATUS_FINISH) {
            return self::dataError('订单已完成');
        }
        if ($order['shipping_status'] == 0) {
            return self::dataError('订单未发货');
        }
        $order->order_status = \app\common\model\Order::STATUS_FINISH;
        $order->update_time = time();
        $order->confirm_take_time = time();
        $order->save();

        //订单日志
        OrderLogLogic::record(
            OrderLog::TYPE_USER,
            OrderLog::USER_CONFIRM_ORDER,
            $order_id,
            $user_id,
            OrderLog::USER_CONFIRM_ORDER
        );

        return self::dataSuccess('确认成功');
    }


    public static function orderTraces($id, $user_id)
    {
        $order = new Order();
        $order = $order->alias('o')
            ->join('order_goods og', 'o.id = og.order_id')
            ->join('goods g', 'g.id = og.goods_id')
            ->where(['o.id' => $id, 'user_id' => $user_id, 'pay_status' => \app\common\model\Order::STATUS_WAIT_DELIVERY, 'o.del' => 0])
            ->field('o.id,order_status,total_num,image,consignee,mobile,province,city,district,address,pay_time,confirm_take_time,o.shipping_status,shipping_time,o.delivery_id')
            ->append(['delivery_address'])
            ->find();

        if (!self::checkDelivery($order['delivery_id'])) {
            return false;
        }

        //初始化数据
        $order_tips = '已下单';
        $order_traces = [];
        $traces = [];//物流轨迹
        $shipment = [//发货
            'title' => '已发货',
            'tips' => '',
            'time' => '',
        ];
        $finish = [//交易完成
            'title' => '交易完成',
            'tips' => '',
            'time' => '',
        ];

        if ($order) {
            $order_delivery = Db::name('delivery')->where(['order_id' => $id])->field('invoice_no,shipping_name,shipping_id')->find();
            $express = ConfigServer::get('express', 'way', '', '');
            //已发货
            if ($express && $order['shipping_status']) {
                $app = ConfigServer::get($express, 'appkey', '', '');
                $key = ConfigServer::get($express, 'appsecret', '', '');
                //获取物流配置
                if ($app && $key) {
                    //快递配置设置为快递鸟时
                    if ($express === 'kdniao') {
                        $expressage = (new Kdniao($app, $key, Env::get('app.app_debug', true)));
                        $shipping_field = 'codebird';
                    } else {
                        $expressage = (new Kd100($key, $app, Env::get('app.app_debug', true)));
                        $shipping_field = 'code100';
                    }
                    //快递编码
                    $shipping_code = Db::name('express')->where(['id' => $order_delivery['shipping_id']])->value($shipping_field);
                    //获取物流轨迹
                    $expressage->logistics($shipping_code, $order_delivery['invoice_no']);
                    $traces = $expressage->logisticsFormat();

                    //获取不到物流轨迹时
                    if ($traces == false) {
                        $traces[] = ['暂时物流信息'];

                    } else {
                        foreach ($traces as &$item) {
                            $item = array_values(array_unique($item));
                        }
                    }

                }
            }
            //待收货
            if ($order['order_status'] == 2) {
                $shipment['tips'] = '商品已出库';
                $shipment['time'] = $order['shipping_time'];
            }
            //确认收货
            if ($order['order_status'] == 3) {
                $order_tips = '交易完成';
                $finish['tips'] = '订单交易完成';
                $finish['time'] = $order['confirm_take_time'];
            }
            //数据合并
            $order_traces = [
                'order' => [
                    'tips' => $order_tips,
                    'image' => UrlServer::getFileUrl($order['image']),
                    'count' => $order['total_num'],
                    'invoice_no' => $order_delivery['invoice_no'],
                    'shipping_name' => $order_delivery['shipping_name'],
                ],
                'take' => [
                    'contacts' => $order['consignee'],
                    'mobile' => $order['mobile'],
                    'address' => $order['delivery_address'],
                ],
                'finish' => $finish,
                'delivery' => [
                    'title' => '运输中',
                    'traces' => $traces
                ],
                'shipment' => $shipment,
                'buy' => [
                    'title' => '已下单',
                    'tips' => '订单提交成功',
                    'time' => $order['pay_time']
                ],
            ];
            return $order_traces;
        }
        return $order_traces;
    }


    //配送方式无需快递的
    public static function checkDelivery($delivery_id)
    {
        $delivery = Db::name('delivery')
            ->where(['id' => $delivery_id])
            ->find();

        if ($delivery['send_type'] == 2) {
            return false;
        }
        return true;
    }

    /**
     * 审核
     * @param $order_id
     * @param $order_status
     * @return Order|bool|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function audit($order_id, $order_status, $user_info)
    {
        $old_status = (new Order())->where("id", $order_id)->field("id,order_status,user_id,order_type,schedule,supplier_id,commission")->find();

        if (!in_array($order_status, self::$status[$old_status['order_status']])) {
            return false;
        }

        Db::startTrans();
        try {
            $model = (new Order());

            if ($order_status == 1) {
                if ($old_status['order_type'] == 0) {  //0主播订单
                    $host_id = $old_status['user_id'];
                    $start_type = 0;
                } elseif ($old_status['order_type'] == 1) {  //1商户订单
                    $host_id = $old_status['supplier_id'];
                    $start_type = 1;
                }

                $schedule = Db::name("schedule")->field("id")->where("schedule", $old_status['schedule'])->where("host_id", $host_id)->find();
                if (empty($schedule)) {
                    $schedule_data = [
                        "host_id" => $host_id,
                        "schedule" => $old_status['schedule'],
                        "expect_commission" => $old_status['commission'],
                        "platform" => $old_status['platform'],
                        "label" => $old_status['label'],
                        "start_type" => $start_type
                    ];
                    $schedule_id = Db::name("schedule")->insertGetId($schedule_data);

                    $res = $model->allowField(true)->where("id", $order_id)->data(["order_status" => $order_status, "schedule_id" => $schedule_id])->update();
                }
            }

            // 日志
            if ($user_info['user_role'] && $user_info['user_role'] == 1) { // 主播审核
                OrderLogLogic::record(
                    OrderLog::TYPE_USER,
                    OrderLog::HOST_CONFIRM_ORDER,
                    $order_id,
                    $user_info['id'],
                    OrderLog::HOST_CONFIRM_ORDER
                );
            } elseif ($user_info['user_role'] && $user_info['user_role'] == 2) { // 商户审核
                OrderLogLogic::record(
                    OrderLog::TYPE_SHOP,
                    OrderLog::SHOP_CONFIRM_ORDER,
                    $order_id,
                    $user_info['id'],
                    OrderLog::SHOP_CONFIRM_ORDER
                );
            }
            Db::commit();
            return $res;
        } catch (\Exception $e) {
            Db::rollback();
            return $e->getMessage();
        }
    }

    /**
     * 付押金
     * @param $post
     * @param $user_id
     * @return array|string
     * @throws Exception
     * @throws \think\db\exception\DbException
     * @throws \think\exception\PDOException
     */
    public static function depositPay($post, $user_id)
    {
        $money = config("project.deposit");

        $user = UserLogic::myWallet($user_id);
        if ($money > $user['user_money']) {
            return self::dataError("余额不足,请充值后再试");
        }

        Db::startTrans();
        $change_type = 2; //1-增加；2-减少
        $remark = "支付押金";
        try {
            $schedule = Db::name("schedule")
                ->field("id,host_id,schedule_sn")
                ->where("id", $post['schedule_id'])
                ->where("host_id", $post['host_id'])
                ->find();

            //日志
            $source_type = AccountLog::balance_pay_order;
            $account_log = [$user_id, $money, $change_type, $source_type, $remark, $schedule['id'], $schedule['schedule_sn']];

            // 档期
            Db::name("schedule")->where("id", $post['schedule_id'])->update([
                "schedule_status" => 1,
                "deposit" => $money
            ]);

            // 余额
            $update_data['user_money'] = Db::raw("user_money-" . $money);
            $result = Db::name('user')->where('id', $user_id)->update($update_data);
            if (!$result) {
                return self::dataError("付款失败");
            }

            AccountLogLogic::AccountRecord(...$account_log);
            Db::commit();
            return self::dataSuccess("付款成功");
        } catch (Exception $e) {
            Db::rollback();
            return self::dataError("付款失败:" . $e->getMessage());
        }
    }

    /**
     * @param $post
     * @param $user_id
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function pay($post, $user_id)
    {
        $schedule = Db::name("schedule")->field("id,sample_price,basis_use,basis_staff")->where([["id","=",$post['schedule_id']],["host_id","=",$post['host_id']]])->find();
        $money = bcadd($schedule['sample_price'],$schedule['basis_use'],$schedule['basis_staff']); // 总计

        $user = UserLogic::myWallet($user_id);
        if ($money > $user['user_money']) {
            return self::dataError("余额不足,请充值后再试");
        }
        // @todo
    }
}
